李守中

SSH 连接建立与认证

本文主要描述 SSH 链接建立与认证的一般过程。

前提: 服务器有自己的公钥和私钥,客户端有自己的公钥和私钥,并且服务器要被连接的用户的 ~/.ssh/authorized_keys 中记录了客户端的公钥。

SSH 连接建立要经历以下过程 (SSH 协议的不同实现在细节上有不同,以 OpenSSH 为例):

  1. 连接建立: 客户端向远程服务器发起 SSH 连接请求并建立连接
  2. 协商通信方式: 客户端与服务器协商协议版本、密钥交换算法、身份认证方法、压缩算法等等内容
  3. 使用密钥交换算法 (DH/ECDH) 协商对称加密密钥:
    • 客户端与服务器使用协商出的密钥交换算法 (DH/ECDH 算法) 协商出对称加密密钥。此后该会话所有的通信都用该密钥加密
  4. 客户端确认服务器身份: 服务器把自己的公钥发给客户端,客户端确认公钥指纹
    • 如果本次服务器发来的公钥指纹在本地没有记录,那就记录服务器的公钥指纹,继续下一步
    • 如果本次服务器发来的公钥指纹与上次记录的指纹匹配,继续下一步
    • 如果本次服务器发来的公钥指纹与上次记录的指纹不匹配,那么可能存在中间人攻击,连接中断
  5. 服务器确认客户端身份:
    • 对于使用密码认证的方式来说
      1. 客户端用服务器的公钥把密码加密后发给服务器
      2. 服务器用自己的私钥解密出密码
      3. 服务器把解密出的密码与本地对应用户的密码比对,若相同,身份验证通过
    • 对于使用非对称加密验证身份的方式来说
      1. 客户端收集当前连接的信息组成待签名数据:
        • 会话 ID (Session ID): 是 SSH 会话的唯一标识符,用于标识当前会话的开始,通常在 SSH 握手过程中生成,并在整个会话期间保持不变
        • 消息类型 (Message Type): 是身份验证请求的消息类型,通常是 SSH2_MSG_USERAUTH_REQUEST。这指示了消息的目的,即执行用户身份验证
        • 用户名 (User Name): 要进行身份验证的用户名,标识要连接的用户
        • 服务名称 (Service Name): 正在请求身份验证的服务的名称。通常,值为 "ssh-connection"
        • 身份验证方法 (Authentication Method): 要使用的身份验证方法,例如 "publickey" (公钥身份验证) 或 "password" (密码身份验证)
        • 签名算法 (Signature Algorithm): 是用于签名待签名数据的签名算法,它指定了如何对数据进行加密和验证
        • 身份密钥 (Identity Key): 用于身份验证的客户端身份密钥的相关信息,通常包括密钥类型、公钥和相关元数据
        • 主机密钥 (Host Key): 如果正在进行主机绑定,还会包括主机密钥的相关信息,用于确保与服务器的通信安全性
      2. 客户端计算待签名信息的 hash 值并用客户端的私钥加密
      3. 客户端把待签名数据和被私钥加密的 hash 值发给服务器
      4. 服务器利用客户端发来的待签名数据再次计算 hash 值
      5. 服务器用客户端的公钥解密出客户端发来的、从客户端生成的、被加密后的 hash 值
      6. 服务器比较两个 hash 值,若相同,身份验证通过
  6. 建立会话: 客户端向服务器端发送会话请求,请求服务器提供某种类型的服务 (Stelnet, SFTP, SCP, NETCONF)

SSH 登录过程中用户需要关注、配置的只有两个阶段:

  1. 使用密钥交换算法 (DH/ECDH) 协商对称加密密钥
    • ssh -Q kex 可以查看当前版本的 OpenSSH 支持什么密钥交换算法
  2. 服务器确认客户端身份
    • 用密码认证还是非对称加密认证
    • ssh -Q key 可以查看当前版本的 OpenSSH 在使用非对称加密的身份认证过程中,支持什么样的密钥类型


Last Update: 2023-11-12 Sun 21:29

Generated by: Emacs 28.2 (Org mode 9.5.5)   Contact: [email protected]

若正文中无特殊说明,本站内容遵循: 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议